<template>
  <el-form ref="ruleFormRef" :label-width="labelWidth + 'px'" :model="formData" :rules="rules" v-bind="$attrs">
    <el-row>
      <el-col v-for="(item, index) in fromTypeList" :key="index" :span="item.span">
        <el-form-item v-if="isEdit" :label="item.label" :prop="item.isRequire ? item.valueKey : null">
          <!-- 单选 -->
          <el-radio-group v-if="item.type == 'radio'" v-model="formData[item.valueKey]" :disabled="item.disabled">
            <el-radio v-for="(dict, num) in item.options" :key="num" :value="dict.value">{{ dict.label }}
            </el-radio>
          </el-radio-group>

          <!-- 下拉框 -->
          <el-select v-else-if="item.type == 'select'" v-model="formData[item.valueKey]" :disabled="item.disabled"
                     :filterable="item.filterable" :multiple="item.multiple" :placeholder="item.placeholder">
            <el-option v-for="(dict, num) in item.options" :key="num" :label="dict.label" :value="dict.value"/>
          </el-select>

          <!-- 日期 -->
          <el-date-picker v-else-if="item.type == 'dateTime'" v-model="formData[item.valueKey]"
                          :disabled="item.disabled" :format="item.format" :placeholder="item.placeholder"
                          :value-format="item.format"
                          style="width: 100%" type="date"/>

          <!-- 复选框 -->
          <el-checkbox-group v-else-if="item.type == 'checkBox'" v-model="formData[item.valueKey]"
                             :disabled="item.disabled">
            <el-checkbox v-for="(dict, num) in item.options" :key="num" :value="dict.value" name="type">
              {{ dict.label }}
            </el-checkbox>
          </el-checkbox-group>

          <!-- 文本框 -->
          <el-input v-else-if="item.type == 'textarea'" v-model.trim="formData[item.valueKey]" :disabled="item.disabled"
                    :maxlength="item.maxlength" :placeholder="item.placeholder"
                    :show-word-limit="item.maxlength ? true : false"
                    type="textarea">
          </el-input>
          <!-- switch -->
          <el-switch v-else-if="item.type == 'switch'" v-model.trim="formData[item.valueKey]"
                     :active-text="item.activeLabel" :disabled="item.disabled" :inactive-text="item.inactiveLabel"
                     :size="item.size"/>

          <!-- 上传附件 -->
          <div v-else-if="item.type == 'files'" style="width: 100%">
            <!--            <upload-files v-model="formData[item.valueKey]" :fileShowType="item.fileShowType"-->
            <!--                          :disabled="item.disabled ? true : false"></upload-files>-->
            <el-upload v-if="item.type == 'files'" :auto-upload="false" :file-list="files"
                       :http-request="handleFileUpload" :limit="5" :multiple="true" :on-change="handleChange"
                       :on-exceed="handleExceed" :on-preview="handlePictureCardPreview" :on-remove="handleFileRemove"
                       class="upload-files" list-type="picture-card">
              <i class="el-icon-plus"></i>
            </el-upload>
          </div>

          <!--          &lt;!&ndash; 输入框 &ndash;&gt;-->
          <!--          <el-input v-else-if="item.type == 'activeInput'" :disabled="item.disabled ? true : false"-->
          <!--                    v-model.trim="formData[item.valueKey]" :placeholder="item.placeholder"-->
          <!--                    @focus="(event) => focusClick(event, item)">-->
          <!--            <template #suffix v-if="item.icon">-->
          <!--              <el-icon class="el-input__icon" v-if="item.icon == 'ArrowDownBold'">-->
          <!--                <ArrowDownBold/>-->
          <!--              </el-icon>-->
          <!--            </template>-->
          <!--          </el-input>-->

          <!-- 数字输入框 -->
          <el-input-number v-else-if="item.type == 'numberInput'" v-model="formData[item.valueKey]" :controls="false"
                           :disabled="item.disabled" :max="item.max" :min="item.min" :placeholder="item.placeholder"
                           style="width: 100%"/>
          <!-- 表格 -->

          <!-- <el-table
            v-else-if="item.type == 'table'"
            :data="formData[item.valueKey]"
            :border="item.border"
            :height="item.height ? item.height : 200"
          >
            <el-table-column label="序号" width="100" align="center">
              <template #default="scope">
                {{ scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column
              v-for="(ele, nums) in item.columnList"
              :key="nums"
              :prop="ele.prop"
              :label="ele.label"
              :align="ele.align"
              :width="ele.width"
            >
              <template #default="scope">
                <span v-if="ele.type == 'date'">
                  {{ timeFormat(scope.row[ele.prop], "{y}-{m}-{d}") }}
                </span>
                <span v-else>{{ scope.row[ele.prop] }}</span>
              </template>
            </el-table-column>
          </el-table> -->

          <!--          <innerEdit-->
          <!--            v-else-if="item.type == 'table'"-->
          <!--            :table-data="formData[item.valueKey]"-->
          <!--            :columns="item.columnList"-->
          <!--            :border="item.border"-->
          <!--            :height="item.height ? item.height : 200"-->
          <!--            class="innerTable"-->
          <!--            :isDetile="false"-->
          <!--            :isBorder="true"-->
          <!--          />-->
          <el-input v-else-if="item.type == 'password'" v-model.trim="formData[item.valueKey]" :disabled="item.disabled"
                    :placeholder="item.placeholder" show-password>
          </el-input>
          <el-input v-else-if="item.type == 'input'" v-model.trim="formData[item.valueKey]" :disabled="item.disabled"
                    :placeholder="item.placeholder">
          </el-input>

          <!-- 在这里添加插槽，允许父组件插入自定义内容 -->
          <slot v-else :formData="formData" :item="item" :name="`formItem-${item.valueKey}`"></slot>
        </el-form-item>

        <el-form-item v-else :label="item.label" :prop="item.isRequire ? item.valueKey : null">
          <span v-if="['radio', 'select', 'checkBox'].indexOf(item.type) > -1">
            {{
              item.options.findIndex((opt) => {
                return opt.value === formData[item.valueKey];
              }) > -1
                  ? item.options[
                      item.options.findIndex((opt) => {
                        return opt.value === formData[item.valueKey];
                      })
                      ].label
                  : props.selectValueErrorMsg
            }}
            <!-- {{ item.options }} -->
          </span>

          <el-table
              class="upgradeTable"
              :row-class-name="'upgradeRow'"
              v-else-if="item.type == 'innerTable'" :border="item.border" :data="formData[item.valueKey]"
              :height="item.height ? item.height : 200">
            <el-table-column align="center" label="序号" width="100">
              <template #default="scope">
                {{ scope.$index + 1 }}
              </template>
            </el-table-column>
            <el-table-column v-for="(ele, nums) in item.columnList" :key="nums" :align="ele.align" :label="ele.label"
                             :prop="ele.prop" :width="ele.width">
              <template #default="scope">
                <span v-if="ele.type == 'date'">
                  {{ timeFormat(scope.row[ele.prop], "{y}-{m}-{d}") }}
                </span>
                <span v-if="ele.type == 'select'">
                  {{
                    ele.options[
                        ele.options.findIndex((opt) => {
                          return opt.value === scope.row[ele.prop];
                        })
                        ].label
                  }}
                </span>
                <span v-else>{{ scope.row[ele.prop] }}</span>
              </template>
            </el-table-column>
          </el-table>

          <span v-else-if="typeof item.showTxt !== 'undefined'">{{ executeFun(item['showTxt'], formData) }}</span>

          <span v-else>{{ formData[item.valueKey] }}</span>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script lang="ts" setup>
import {
  ref,
  toRefs,
  watch,
  computed,
} from "vue";

import {ElForm, ElMessage} from "element-plus";
import {cloneDeep, timeFormat} from "@/utils";

// 定义更具体的 prop 类型
interface FormItem {
  span: number;
  label: string;
  isRequire: boolean;
  valueKey: string;
  showTxt: () => string;
  type: string;
  options: Array<{ value: any; label: string }>;
  disabled: boolean;
  multiple: boolean;
  placeholder?: string;
  format?: string;
  filterable: boolean;
  maxlength?: number;
  fileShowType?: any;
  max?: number;
  min?: number;
  border?: boolean;
  height?: number;
  dataSource?: any[];
  columnList?: Array<{
    prop: string;
    label: string;
    align: string;
    width: string;
    type?: string;
  }>;
  icon?: string;
  size?: string;
  activeLabel?: string;
  inactiveLabel?: string;
}

const props = defineProps({
  formList: {
    type: Array<FormItem>,
    default: () => {
      return [];
    },
  },
  formRules: {
    type: Object,
    default: () => {
      return {};
    },
  },
  labelWidth: {
    type: Number,
    default: 150,
  },
  isClose: {
    type: Boolean,
    default: () => {
      return false;
    },
  },
  isSubmit: {
    type: Boolean,
    default: () => {
      return false;
    },
  },
  isInFile: {
    type: Boolean,
    default: () => {
      return false;
    },
  },
  isEdit: {
    type: Boolean,
    default: () => {
      return true;
    },
  },
  formData: {
    type: Object,
    default: () => {
      return {};
    },
  },
  index: {
    type: [Number, null],
    default: () => {
      return null;
    },
  },
  selectValueErrorMsg: {
    type: String,
    default: () => {
      return "";
    },
  },
});

const files = ref([]);

const dialogImageUrl = ref("");
const dialogVisible = ref(false);

// 处理文件上传（实际上在这里我们并不真正上传文件，只是添加到fileList中）
const handleFileUpload = ({file, onSuccess, onError}) => {
  // fileList.value.push(file); // 将文件添加到fileList中
  // console.log(fileList)
  onSuccess(); // 通知element-ui上传成功（即使我们并没有真正上传）
};

const executeFun = <T, R>(fun: (arg: T) => R, row: T): R => {
  return fun(row);
};

// 处理文件移除
const handleFileRemove = (file, fileList) => {
  const index = files.value.findIndex((f) => f.uid === file.uid);
  if (index > -1) {
    files.value.splice(index, 1); // 从fileList中移除文件
  }
};

// 处理文件数量超过限制
const handleExceed = (files, fileList) => {
  ElMessage.warning(
      `当前限制选择 5 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`,
  );
};

// 处理文件状态变化（可选）
const handleChange = (file, fileList) => {
  files.value.push(file);
  console.log(files.value, 112);
};

// 处理图片预览
const handlePictureCardPreview = (file) => {
  dialogImageUrl.value = file.url;
  dialogVisible.value = true;
};

// 定义 emit 事件
const emit = defineEmits(["updateData", "uData"]);

// 响应式数据
const ruleFormRef = ref(null);

// 如果需要将 props 转换为响应式引用
const fromTypeList = computed(() => {
  let list = cloneDeep(props.formList)
  if (!props.isEdit) {
    list = list.map(item => {
      if (item.type === 'innerTable') {
        item['columnList'] = item['columnList']?.map(col => {
          if (col['operate']) {
            return false
          } else {
            return col
          }
        }).filter(s => {
          if (s) {
            return s
          }
        })
      }
      return item
    }).filter(s => {
      if (s) {
        return s
      }
    })
    // return props.formList
  }
  return list
}); // 使用 computed 替代 toRefs
const rules = computed(() => props.formRules);

// 提交表单
const submitForm = async () => {
  if (ruleFormRef.value) {
    try {
      const valid = await ruleFormRef.value.validate(); // 假设validate返回一个Promise
      if (valid) {
        // 表单验证通过，执行提交操作
        console.log("表单验证通过");
        // 这里可以添加实际的提交逻辑，比如发送请求到服务器
      } else {
        // 表单验证失败，可以在这里处理错误，比如显示错误消息
        console.log("表单验证失败");
      }
      return valid;
    } catch (error) {
      // 处理验证过程中可能发生的错误
      console.error("验证过程中发生错误:", error);
      return false;
    }
  } else {
    console.log("表单实例不存在");
    return false;
  }
};

const {formData, isClose, isSubmit} = toRefs(props);

// 监听数据发生改变，将数据抛出
// watch(() => formData.value, (newD, oldD) => {
//   submitForm().then(valid => {
//     emit('uData', {valid, data: newD});
//   })
// }, {deep: true})

watch(
    () => isClose.value,
    (newD, oldD) => {
      if (newD && ruleFormRef.value) {
        // 重置表单
        // ruleFormRef.value.resetFields()
        // 清除检查
        ruleFormRef.value.clearValidate();
      } else if (!newD && ruleFormRef.value) {
        // 重置表单
        ruleFormRef.value.resetFields();
      }
    },
);

watch(
    () => isSubmit.value,
    (newD, oldD) => {
      if (newD) {
        submitForm().then((valid) => {
          let data = props.isInFile
              ? {
                ...formData.value,
                fileList: files.value,
              }
              : formData.value;
          emit("uData", {
            valid,
            data,
            index: props.index,
          });
        });
      }
    },
);
</script>

<style lang="scss" scoped>
@import "@/assets/var";

.upgradeTable {
  overflow: auto;
  font-size: $--table-size;
  color: $--table-color;
  background: $--table-bg;
  //box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.5);

  & ::v-deep(.el-table__row.upgradeRow) {
    background: $--table-tr-bg;

    &:hover {
      color: $--table-row-hover-color;
    }

    //&.el-table__row{
    //  :hover{
    //    background: red;
    //  }
    //}
  }

  ::v-deep(.el-table__header-wrapper th) {
    /* 自定义表头样式 */
    & tr {
      background: $--table-th-bg;
    }

    background: $--table-th-bg;
    color: $--table-th-color;
    font-size: 14px;
  }
}
</style>
